/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "transformation/transformation_factory.h"
#include "transformation_base.h"
#include "transformation_blur.h"
#include "transformation_brighten.h"
#include "transformation_gray_scale.h"
#include "transformation_invert.h"
#include "transformation_kuwahara.h"
#include "transformation_pixelation.h"
#include "transformation_sketch.h"
#include "transformation_sepia.h"
#include "transformation_swirl.h"
#include "transformation_toon.h"
#include "transformation_vignette.h"
#include "transformation_crop_square.h"
#include "transformation_crop_circle.h"
#include "transformation_crop_circle_with_border.h"
#include "transformation_mask.h"
#include "transformation_crop.h"
#include "transformation_mirror.h"

namespace ImageKnifePro {

typedef std::shared_ptr<Transformation> TransformPtr;
typedef std::shared_ptr<TransformationOption> OptionPtr;

TransformPtr TransformationFactory::CreateTransformation(OptionPtr option)
{
    IMAGE_KNIFE_CHECK_RETURN(option == nullptr, nullptr, "TransformationOption Is Null");
    typedef std::function<TransformPtr(OptionPtr)> Builder;
    static std::unordered_map<TransformationType, Builder> builderMap = {
        {TransformationType::UNKNOWN, [](OptionPtr option) -> TransformPtr {return nullptr;}},
        {TransformationType::BLUR, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationBlur>(option);}},
        {TransformationType::BRIGHTEN, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationBrighten>(option);}},
        {TransformationType::GRAY_SCALE, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationGrayScale>();}},
        {TransformationType::INVERT, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationInvert>();}},
        {TransformationType::KUWAHARA, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationKuwahara>(option);}},
        {TransformationType::PIXELATION, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationPixelation>(option);}},
        {TransformationType::SEPIA, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationSepia>(option);}},
        {TransformationType::SKETCH, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationSketch>();}},
        {TransformationType::SWIRL, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationSwirl>(option);}},
        {TransformationType::TOON, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationToon>(option);}},
        {TransformationType::VIGNETTE, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationVignette>(option);}},
        {TransformationType::CROP_SQUARE, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCropSquare>();}},
        {TransformationType::CROP_CIRCLE, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCropCircle>();}},
        {TransformationType::CROP_CIRCLE_WITH_BORDER, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCropCircleWithBorder>(option);}},
        {TransformationType::MASK, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationMask>(option);}},
        {TransformationType::CROP_TOP, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCrop>(option);}},
        {TransformationType::CROP_CENTER, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCrop>(option);}},
        {TransformationType::CROP_BOTTOM, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationCrop>(option);}},
        {TransformationType::MIRROR, [](OptionPtr option) -> TransformPtr {
            return std::make_shared<TransformationMirror>();}},
    };

    auto func = builderMap[option->type];
    return func(option);
}
}
